package com.mintrust.customer.service.impl.base;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.mintrust.common.enums.CodeMessageEnum;
import com.mintrust.common.exception.FiveMineException;
import com.mintrust.common.utils.EmptyUtil;
import com.mintrust.customer.service.sdk.base.BaseService;
import com.mintrust.repository.base.BasePage;
import com.mintrust.repository.config.CommonMapper;
import com.mintrust.repository.model.User;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * Created by  pengpeng.zhang 2018/7/23
 */
public abstract class BaseServiceImpl<T> implements BaseService<T> {

    protected Logger logger = LoggerFactory.getLogger(getClass());

    protected abstract CommonMapper<T> commonMapper();

    @Override
    public void save(T entity) {
        try {
            commonMapper().insert(entity);
        } catch (Exception e) {
            String simpleName = getClass().getSimpleName();
            throw new FiveMineException(CodeMessageEnum.TMS_BASE_COMMON_SAVE_ERROR, simpleName + "保存异常", e);
        }
    }

    @Override
    public void saveList(List<T> list) {
        try {
            if (EmptyUtil.isCollectionEmpty(list)) {
                return;
            }
            commonMapper().insertList(list);
        } catch (Exception e) {
            String simpleName = getClass().getSimpleName();
            throw new FiveMineException(CodeMessageEnum.TMS_BASE_COMMON_SAVELIST_ERROR, simpleName + "批量保存异常", e);
        }
    }

    @Override
    public void updateById(T entity) {
        try {
            commonMapper().updateByPrimaryKeySelective(entity);
        } catch (Exception e) {
            String simpleName = getClass().getSimpleName();
            throw new FiveMineException(CodeMessageEnum.TMS_BASE_COMMON_UPDATEBYID_ERROR, simpleName + "根据主键更新异常", e);
        }
    }

    @Override
    public T selectById(Serializable id) {
        try {
            return commonMapper().selectByPrimaryKey(id);
        } catch (Exception e) {
            String simpleName = getClass().getSimpleName();
            throw new FiveMineException(CodeMessageEnum.TMS_BASE_COMMON_SELECTBYID_ERROR, simpleName + "根据主键查询异常", e);
        }
    }

    @Override
    public T selectOne(T entity) {
        try {
            return commonMapper().selectOne(entity);
        } catch (Exception e) {
            String simpleName = getClass().getSimpleName();
            throw new FiveMineException(CodeMessageEnum.TMS_BASE_COMMON_SELECTONE_ERROR, simpleName + "根据实体查询唯一一条异常", e);
        }
    }

    @Override
    public List<T> select(T entity) {
        try {
            return commonMapper().select(entity);
        } catch (Exception e) {
            String simpleName = getClass().getSimpleName();
            throw new FiveMineException(CodeMessageEnum.TMS_BASE_COMMON_SELECT_ERROR, simpleName + "根据实体查询异常", e);
        }
    }

    @Override
    public List<T> selectAll() {
        try {
            return commonMapper().selectAll();
        } catch (Exception e) {
            String simpleName = getClass().getSimpleName();
            throw new FiveMineException(CodeMessageEnum.TMS_BASE_COMMON_SELECTALL_ERROR, simpleName + "查询所有异常", e);
        }
    }

    @Override
    public void deleteById(Serializable id) {
        try {
            commonMapper().deleteByPrimaryKey(id);
        } catch (Exception e) {
            String simpleName = getClass().getSimpleName();
            throw new FiveMineException(CodeMessageEnum.TMS_BASE_COMMON_DELETEBYID_ERROR, simpleName + "查询所有异常", e);
        }
    }

    @Override
    public void delete(T entity) {
        try {
            commonMapper().delete(entity);
        } catch (Exception e) {
            String simpleName = getClass().getSimpleName();
            throw new FiveMineException(CodeMessageEnum.TMS_BASE_COMMON_DELETE_ERROR, simpleName + "查询所有异常", e);
        }
    }

    @Override
    public PageInfo<T> selectListByCondition(BasePage basePage, Class<T> clazz) {
        try {
            Integer pageNum = basePage.getPageNum();
            Integer pageSize = basePage.getPageSize();

            Example example = new Example(clazz);
            Example.Criteria criteria = example.createCriteria();
            setupBasePageCondition(basePage, criteria);
            Map<String, Object> map = JSON.parseObject(JSON.toJSONString(basePage), new TypeReference<Map<String, Object>>() {
            });
            logger.info("@@@"+JSON.toJSONString(map));
            map.remove("pageNum");
            map.remove("pageSize");
            map.remove("start");
            map.remove("end");
            map.remove("sortName");
            map.remove("sortType");
            map.remove("createBy");
            map.remove("updateBy");
            map.remove("sortCondition");
            if (!extendCriteria(criteria, map)) {
                return new PageInfo<>();
            }
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                if (value != null) {
                    if (value instanceof String && StringUtils.isNotBlank((String) value)) {
                        criteria.andLike(key, "%" + (String) value + "%");
                    }
                    if (!(value instanceof String)) {
                        criteria.andEqualTo(key, value);
                    }
                }
            }
            PageHelper.startPage(pageNum, pageSize, basePage.getSortCondition());
            List<T> exampleList = commonMapper().selectByExample(example);
            return new PageInfo<>(exampleList);
        } catch (Exception e) {
            String simpleName = getClass().getSimpleName();
            throw new FiveMineException(CodeMessageEnum.TMS_BASE_COMMON_SELECTBYCONDITION_ERROR, simpleName + "条件及分页查询异常", e);
        }
    }

    protected void setupBasePageCondition(BasePage basePage, Example.Criteria criteria) {
        if (basePage.getEnd() != null) {
            criteria.andLessThanOrEqualTo("createTime", basePage.getEnd());
        }
        if (basePage.getStart() != null) {
            criteria.andGreaterThanOrEqualTo("createTime", basePage.getStart());
        }
        if (EmptyUtil.isStringTrimNotEmpty(basePage.getCreateBy())) {
            criteria.andLike("createBy", "%" + basePage.getCreateBy() + "%");
        }
        if (EmptyUtil.isStringTrimNotEmpty(basePage.getUpdateBy())) {
            criteria.andLike("updateBy", "%" + basePage.getUpdateBy() + "%");
        }
    }

    /**
     * 扩展Criteria的功能
     *
     * @param criteria Example中的Criteria
     * @param basePage 查询条件
     * @return true 继续查询数据库。false 无需查询数据库，数据结果一定为空
     */
    protected boolean extendCriteria(Example.Criteria criteria, Map<String, Object> basePage) {
        return true;
    }

    @Override
    public User getOperator() {
        final HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        final Object operator = request.getAttribute("operator");
        if (operator instanceof User) {
            return (User) operator;
        } else {
            return null;
        }
    }
}
